using System;
using System.IO;
using System.Text;
using System.Threading;
using System.Collections.Generic;

using Microsoft.SPOT.Hardware;
using Microsoft.SPOT.Emulator;
using Microsoft.SPOT.Emulator.Spi;
using Microsoft.SPOT.Emulator.Gpio;

namespace $rootnamespace$
{
    /// <summary>This is a template for an emulated SPI Device</summary>
    /// <remarks>
    /// The device emulated here has a simple protocol. This device suports
    /// one command to read the "Chip ID". Sending the ReadID command (0x5A)
    /// will return the 2 byte ChipID (default=0xAA55) in little-endian order.
    /// </remarks>
    class $safeitemname$ : SpiDevice
    {
        ///<summary>Constructs a new $safeitemname$ with all the default property values</summary>
        public $safeitemname$() 
        {
            // set up all default values here base.COnfigure() may
            // replace theses settings with values from the
            // configuration file

            this._ChipID = 0xAA55;
            this.SpiModule = Spi.SpiModule.Spi1;
            this.ChipSelectActiveState = false;
            this.ChipSelectHoldTime = 1;
            this.ChipSelectSetupTime = 1;
            this.ClockIdleState = false;
            this.ClockEdge = true;
            this.ClockRateKHz = 16000;
        }

        /// <summary>ChipID read from the configuration file</summary>
        /// <remarks>This is an optional value. If not present the default
        /// 0xAA55, set in the constructor, is used.
        /// 
        /// The base EmulatorComponent.Configure() method will read the XML
        /// configuration data for this component instance and match up the
        /// child elements with matching property names. Thus to add custom
        /// settings to the configuration you only need to add a public
        /// property like this one. 
        /// </remarks>
        public ushort ChipID
        {
            get { return this._ChipID; }
            set
            {
                base.ThrowIfNotConfigurable();
                this._ChipID = value;
            }
        }
        private ushort _ChipID;

        /// <summary>Sets or gets the chip select pin by its registered name</summary>
        /// <value>Registered name of the pin</value>
        /// <remarks>
        /// The emulator supports a ComonentID for all components. This property
        /// allows specifiying the GPIO pin data via its Id name. This can 
        /// help keep the XML configuration files simpler, less error prone and
        /// self documenting. This is the recommended way to handle GPIO pins in
        /// emulator components and configuration files. 
        /// </remarks>
        public string PinName
        {
            get
            { 
                return base.Emulator.GpioPorts[this.Pin].ComponentId;
            }
            set
            {
                GpioPort ssPin = (GpioPort)base.Emulator.FindComponentById(value);
                this.Pin = ssPin.Pin;
            }
        }

        ///<summary>Performs a write/read operation for the device.</summary>
        protected override byte[] Write(byte[] data)
        {
            if(data.Length != 1 || (data[0] != 0x5A))
                throw new ArgumentException();

            byte[] retVal = new byte[2];            
            retVal[0] = (byte)(this._ChipID & 0xFF);
            retVal[1] = (byte)(this._ChipID >> 8);
            return retVal;
        }
    }
}
